hvm: passthrough MSI-X: fix ia64 link and MSI-X clean up
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 3 Mar 2009 11:46:52 +0000 (11:46 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 3 Mar 2009 11:46:52 +0000 (11:46 +0000)
This patch fixes the ia64 link error and some clean up of MSI-X code.
- add ia64 dummy function to link
- fix unmatched prototype
- add error check

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
xen/arch/ia64/vmx/vmx_interrupt.c
xen/arch/x86/hvm/vmsi.c
xen/drivers/passthrough/io.c
xen/include/xen/pci.h

index c7939f7ced67532c3ccddf3b04aab140861b9595..aa3b6296613bfd01595936cdb6778af293e5dd51 100644 (file)
@@ -154,3 +154,14 @@ void hvm_isa_irq_deassert(struct domain *d, unsigned int isa_irq)
 {
     /* dummy */
 }
+
+int msixtbl_pt_register(struct domain *d, int pirq, uint64_t gtable)
+{
+    /* dummy */
+    return -ENOSYS;
+}
+
+void msixtbl_pt_unregister(struct domain *d, int pirq)
+{
+    /* dummy */
+}
index 2d10be9345aef30998a5ac8d9b53ce23d7a96137..1a0a45a6c92014930f5e3a9833640d5f0851c970 100644 (file)
@@ -378,14 +378,16 @@ static void del_msixtbl_entry(struct msixtbl_entry *entry)
     call_rcu(&entry->rcu, free_msixtbl_entry);
 }
 
-void msixtbl_pt_register(struct domain *d, int pirq, uint64_t gtable)
+int msixtbl_pt_register(struct domain *d, int pirq, uint64_t gtable)
 {
     irq_desc_t *irq_desc;
     struct msi_desc *msi_desc;
     struct pci_dev *pdev;
     struct msixtbl_entry *entry;
+    int r = -EINVAL;
+
+    ASSERT(spin_is_locked(&pcidevs_lock));
 
-    /* pcidevs_lock already held */
     irq_desc = domain_spin_lock_irq_desc(d, pirq, NULL);
 
     if ( irq_desc->handler != &pci_msi_type )
@@ -412,11 +414,13 @@ void msixtbl_pt_register(struct domain *d, int pirq, uint64_t gtable)
 
 found:
     atomic_inc(&entry->refcnt);
-
     spin_unlock(&d->arch.hvm_domain.msixtbl_list_lock);
+    r = 0;
 
 out:
     spin_unlock_irq(&irq_desc->lock);
+    return r;
+
 }
 
 void msixtbl_pt_unregister(struct domain *d, int pirq)
@@ -426,7 +430,8 @@ void msixtbl_pt_unregister(struct domain *d, int pirq)
     struct pci_dev *pdev;
     struct msixtbl_entry *entry;
 
-    /* pcidevs_lock already held */
+    ASSERT(spin_is_locked(&pcidevs_lock));
+
     irq_desc = domain_spin_lock_irq_desc(d, pirq, NULL);
 
     if ( irq_desc->handler != &pci_msi_type )
index 9e5c230bb76436aa68289847289e0469e34a949a..d02bf382aab14ee8874066b93a4076406b4b5784 100644 (file)
@@ -58,14 +58,6 @@ static void pt_irq_time_out(void *data)
     pirq_guest_eoi(irq_map->dom, machine_gsi);
 }
 
-#ifdef CONFIG_X86
-extern void msixtbl_pt_register(struct domain *d, int pirq, uint64_t gtable);
-extern void msixtbl_pt_unregister(struct domain *d, int pirq);
-#else
-#define msixtbl_pt_register(d, p, g) ((void)0)
-#define msixtbl_pt_unregister(d, p)  ((void)0)
-#endif
-
 int pt_irq_create_bind_vtd(
     struct domain *d, xen_domctl_bind_pt_irq_t *pt_irq_bind)
 {
@@ -113,6 +105,12 @@ int pt_irq_create_bind_vtd(
             hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] = pirq;
             /* bind after hvm_irq_dpci is setup to avoid race with irq handler*/
             rc = pirq_guest_bind(d->vcpu[0], pirq, 0);
+            if ( rc == 0 && pt_irq_bind->u.msi.gtable )
+            {
+                rc = msixtbl_pt_register(d, pirq, pt_irq_bind->u.msi.gtable);
+                if ( unlikely(rc) )
+                    pirq_guest_unbind(d, pirq);
+            }
             if ( unlikely(rc) )
             {
                 hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] = 0;
@@ -123,8 +121,6 @@ int pt_irq_create_bind_vtd(
                 spin_unlock(&d->event_lock);
                 return rc;
             }
-            if ( pt_irq_bind->u.msi.gtable )
-                msixtbl_pt_register(d, pirq, pt_irq_bind->u.msi.gtable);
         }
         else if (hvm_irq_dpci->mirq[pirq].gmsi.gvec != pt_irq_bind->u.msi.gvec
                 ||hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] != pirq)
index c60b8e369118c84904a13973ed978198773e34c1..34f79b7a813d11592a7c98e6dcba03f98b06c756 100644 (file)
@@ -85,4 +85,7 @@ void pci_conf_write32(
 int pci_find_cap_offset(u8 bus, u8 dev, u8 func, u8 cap);
 int pci_find_next_cap(u8 bus, unsigned int devfn, u8 pos, int cap);
 
+int msixtbl_pt_register(struct domain *d, int pirq, uint64_t gtable);
+void msixtbl_pt_unregister(struct domain *d, int pirq);
+
 #endif /* __XEN_PCI_H__ */